# -*- coding: utf-8 -*-
# created on 2017/03/28

from mathsolver.functions.base import BaseFunction, BaseEq, BasePoint, BaseVariable
from mathsolver.functions.hanshu.dingyiyu import QiuDingYiYu
from mathsolver.functions.hanshu.helper import get_randn_from_interval, allclose


class DuiChengPanDuan(BaseFunction):
    """判断函数是否关于 
        - 直线 x = m
        - 点 (m, n)
        - 直线 y = x
        - 直线 y = -x 对称"""

    def solver(self, *args):

        if len(args) == 1:
            func = args[0]
            eq_or_point = BasePoint({'name': '', 'value': ['0', '0']})
        else:
            func, eq_or_point = args

        expr, var = func.expression, func.var

        dingyiyu = QiuDingYiYu().solver(func)

        # case 2: 点 (m, n)
        if isinstance(eq_or_point, BasePoint):
            m, n = eq_or_point.sympify()
            result = duicheng_panduan_mn(expr, var, dingyiyu, m, n)
        elif isinstance(eq_or_point, BaseEq):
            l_val, r_val = eq_or_point.sympify()
            # case 1: x = m
            if str(l_val) == 'x':
                result = duicheng_panduan_xm(expr, var, dingyiyu, r_val)
            elif str(l_val) == 'y' and str(r_val) == 'x':
                result = duicheng_panduan_yx(expr, var, dingyiyu)
            elif str(l_val) == 'y' and str(r_val) == '-x':
                result = duicheng_panduan_yminusx(expr, var, dingyiyu)
            else:
                raise ValueError('未知 BaseEq 输入格式')
        else:
            raise ValueError('输入类型必须为BasePoint 或者 BaseEq 格式')

        self.output.append(BaseVariable(result))
        return self


def duicheng_panduan_xm(expr, var, dingyiyu, m):
    """判断函数是否关于 直线 x = m 对称"""

    # 从定义域里面取 10 个点， f(x) == f(2m-x)
    xs = get_randn_from_interval(dingyiyu, 10)
    return allclose([expr.subs(var, x1).evalf() for x1 in xs],
                    [expr.subs(var, 2 * m - x2).evalf() for x2 in xs])


def duicheng_panduan_mn(expr, var, dingyiyu, m, n):
    """判断函数是否关于 点 (m, n) 对称"""

    # 从定义域里面取 10 个点， f(x) == 2n - f(2m-x)
    xs = get_randn_from_interval(dingyiyu, 10)
    return allclose([expr.subs(var, x1).evalf() for x1 in xs],
                    [(2 * n - expr.subs(var, 2 * m - x2)).evalf() for x2 in xs])


def duicheng_panduan_yx(expr, var, dingyiyu):
    """判断函数是否关于 直线 y = x 对称"""

    # 从定义域里面取 10 个点， f(f(x)) == x
    xs = get_randn_from_interval(dingyiyu, 10)
    return allclose(xs, [expr.subs(var, expr.subs(var, x1)).evalf() for x1 in xs])


def duicheng_panduan_yminusx(expr, var, dingyiyu):
    """判断函数是否关于 直线 y = -x 对称"""

    # 从定义域里面取 10 个点， f(-f(x)) == -x
    xs = get_randn_from_interval(dingyiyu, 10)
    return allclose([-x1 for x1 in xs], [expr.subs(var, -expr.subs(var, x2)).evalf() for x2 in xs])


if __name__ == '__main__':
    pass
